package com.slt.android.animatest;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LayoutAnimationController;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.slt.android.animatest.custom.CustomTvAnima;
import com.slt.android.animatest.custom.customAnima;

/**
 * 视图动画
 * --不具备交互性，当某个元素发生视图动画后，其响应事件依然在动画前的地方
 * --只能当作效果，应避免交互
 * --效率比较高且使用方便
 * --既可以使用xml来描述又可以使用代码
 * 属性动画
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button btn;
    ImageView iv , iv2;
    ImageView ivb , ivc , ivd;
    ImageView ivb_Copy;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.btn);
        iv = (ImageView) findViewById(R.id.iv);
        ivb = (ImageView) findViewById(R.id.ivb);
        ivc = (ImageView) findViewById(R.id.ivc);
        ivd = (ImageView) findViewById(R.id.ivd);
        ivb_Copy = (ImageView) findViewById(R.id.ivb_copy);
        iv2 = (ImageView) findViewById(R.id.iv2);
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
//        shiTuAnima();
//        shuXingAnima();
//        wrrapViewAnima();
//        propertyValueHodler();
//        valueAnimator();
//        xmlAnima();
//        animaFunction();
//        layoutAnima();
//        layoutAnima2();
        customAnima();
        customAnimaTv();
    }

    private void customAnimaTv() {
        CustomTvAnima anima = new CustomTvAnima();
        anima.setRotateY(60);
        iv.startAnimation(anima);
    }

    /**
     * 自定义动画
     */
    private void customAnima() {
        customAnima anima = new customAnima();
        anima.setRotateY(60);
        ivd.startAnimation(anima);
    }

    private void layoutAnima2() {
        RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl);

        Button btn = new Button(this);
        RelativeLayout.LayoutParams rllp= new RelativeLayout.LayoutParams(200 , 200);
        rllp.addRule(RelativeLayout.CENTER_IN_PARENT);
        btn.setLayoutParams(rllp);


        //设置过度动画
        ScaleAnimation sa = new ScaleAnimation(1 , 2 , 1 ,2);
        sa.setDuration(3000);

        //设置布局动画的显示属性
        LayoutAnimationController lac = new LayoutAnimationController(sa , 0.5f);
        lac.setOrder(LayoutAnimationController.ORDER_REVERSE);
        //为viewgroup设置布局动画
        rl.setLayoutAnimation(lac);


        rl.addView(btn);
    }

    /** 这里是在布局的根部加上android:animateLayoutChanges="true"
     *  效果是加上这一句话，根view在添加新的view的时候会有个过度效果
     *  这个效果是默认的，且不能自定义
     * */
    private void layoutAnima() {
        Button btn = new Button(this);
        RelativeLayout.LayoutParams rllp= new RelativeLayout.LayoutParams(200 , 200);
        rllp.addRule(RelativeLayout.CENTER_IN_PARENT);
        btn.setLayoutParams(rllp);

        RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl);
        rl.addView(btn);
    }

    private void animaFunction() {
        ivd.animate()
                .alpha(0)
                .scaleY(2)
                .setDuration(6000)
                .x(1000)
                .withStartAction(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this , "动画开始..." , Toast.LENGTH_SHORT).show();
                    }
                })
                .withEndAction(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this , "动画结束..." , Toast.LENGTH_SHORT).show();
                    }
                })
                .start();

    }

    private void xmlAnima() {
        scaleX();
    }

    private void scaleX() {
        Animator anima = AnimatorInflater.loadAnimator(this , R.animator.object_animator);
        anima.setTarget(ivd);
        anima.start();
    }

    /** ObjectAnimator是继承自valueAnimator的
     * valueAnimator本身不提供任何动画效果，它更像是一个数值发生器
     * 用来产生具有一定规律的数字，从而让调用者来控制动画的实现过程
     * 通常情况下，在valueAnimator的AnimatorUpdateListener中监听数值的变化，从而完成动画的变化
     * */
    private void valueAnimator() {
        ValueAnimator animtor = ValueAnimator.ofFloat(0 , 100);
        animtor.setTarget(ivd);
        animtor.setDuration(3000);
        animtor.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float value = (Float) animation.getAnimatedValue();

            }
        });
    }

    /** 类似组合动画的东西*/
    private void propertyValueHodler() {
        PropertyValuesHolder ph1 = PropertyValuesHolder.ofFloat("translationX" , 0f , 300f);
        PropertyValuesHolder ph2 = PropertyValuesHolder.ofFloat("scaleX" , 1f , 2f , 1f);
        PropertyValuesHolder ph3 = PropertyValuesHolder.ofFloat("scaleY" , 1f , 2f , 1f);
        ObjectAnimator.ofPropertyValuesHolder(ivd , ph1 , ph2 , ph3).setDuration(3000).start();

    }

    /** 通过设置包装类-强行给ivd设置了一个width属性-并对他进行动画*/
    private void wrrapViewAnima() {
        WrrapView mWrrapView = new WrrapView(ivd);
        ObjectAnimator.ofInt(mWrrapView , "width" , 0 , 500).setDuration(4000).start();
    }

    public static class WrrapView{
        private View mTarget;
        public WrrapView(View target){
            mTarget = target;
        }
        public int getWidth(){
            return mTarget.getLayoutParams().width;
        }
        public void setWidth(int width){
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout();
        }
    }
    /** ObjectAnimator---这里的属性动画，指的是ObjectAnimator*/
    private void shuXingAnima() {
        alphaAnima2();
//        transXAnima();
//        transYAnima();
//        transXYAnima2();
//        roateXAnima();
//        roateYAnima();
//        roateXYAnima();
//        roatePICAnima();
//        dianxinRotate();
//        xAnima();
    }

    private void xAnima() {
        //它的0f起点是重它父容器的左上角开始计算的
        ObjectAnimator animator = ObjectAnimator.ofFloat(ivd , "x" , 0f ,-180f);
        animator.setDuration(5000);
        animator.start();
    }

    private void dianxinRotate() {
        float w = ivb.getMeasuredWidth();
        float h = ivb.getMeasuredHeight();
        ObjectAnimator animator = ObjectAnimator.ofFloat(ivb , "rotationX" , 0f ,-180f);
        ivb.setPivotX(w * 2f);
        ivb.setPivotY(h/2);
        animator.setDuration(5000);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(ivb_Copy , "rotationX" , 0f ,-180f);
        ivb_Copy.setPivotX(w * 2f);
        ivb_Copy.setPivotY(h/2);
        animator2.setDuration(5000);

        ObjectAnimator animatorOut = ObjectAnimator.ofFloat(ivb, "alpha", 1f, 0f);
        final ObjectAnimator animatorIn = ObjectAnimator.ofFloat(ivb_Copy, "alpha", 0f, 1f);
        /** 最中间没有渐变做法开始*/
//        animatorOut.setDuration(2500);
//        animatorIn.setDuration(2500);
//        ivb_Copy.setAlpha(0f);
//        animatorOut.addListener(new Animator.AnimatorListener() {
//            @Override
//            public void onAnimationStart(Animator animation) {
//
//            }
//
//            @Override
//            public void onAnimationEnd(Animator animation) {
//                Toast.makeText(MainActivity.this , "onAnimationEnd" , Toast.LENGTH_SHORT).show();
//                animatorIn.start();
//            }
//
//            @Override
//            public void onAnimationCancel(Animator animation) {
//
//            }
//
//            @Override
//            public void onAnimationRepeat(Animator animation) {
//
//            }
//        });

        /** 控制动画的速度*/
//        animator.setInterpolator(new LinearInterpolator());
//        animator2.setInterpolator(new LinearInterpolator());
//        animatorOut.setInterpolator(new LinearInterpolator());
//        animatorIn.setInterpolator(new LinearInterpolator());
//
//        AnimatorSet animSet = new AnimatorSet();
////        animSet.play(animator).with(animator2).with(animatorOut).with(animatorIn);
//        animSet.play(animator).with(animator2).with(animatorOut);
////        animSet.setDuration(5000);
//        animSet.start();
        /** 最中间没有渐变做法结束*/


        /** 最中间有渐变做法开始*/
        /** 控制动画的速度*/
//        animator.setInterpolator(new LinearInterpolator());
//        animator2.setInterpolator(new LinearInterpolator());
//        animatorOut.setInterpolator(new LinearInterpolator());
//        animatorIn.setInterpolator(new LinearInterpolator());

        AnimatorSet animSet = new AnimatorSet();
        animSet.play(animator).with(animator2).with(animatorOut).with(animatorIn);
        animSet.setDuration(5000);
        animSet.start();
        /** 最中间有渐变做法结束*/

    }

    /** 图片2d旋转一周*/
    private void roatePICAnima() {
        ObjectAnimator animator = ObjectAnimator.ofFloat(ivd , "rotation" , 0f ,360f);
        animator.setDuration(5000);
        animator.start();
    }
    /** 图片绕x和y轴同时3d旋转一周*/
    private void roateXYAnima() {
        ObjectAnimator animatorY = ObjectAnimator.ofFloat(ivc , "rotationY" , 0f ,360f);
        ObjectAnimator animatorX = ObjectAnimator.ofFloat(ivc , "rotationX" , 0f ,360f);
        AnimatorSet animSet = new AnimatorSet();
        animSet.play(animatorX).with(animatorY);
        animSet.setDuration(5000);
        animSet.start();
    }
    /** 图片绕Y轴3d旋转一周*/
    private void roateYAnima() {
        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "rotationY" , 0f ,360f);
        animator.setDuration(5000);
        animator.start();
    }
    /** 图片绕x轴3d旋转一周*/
    /** 通过设置pivotX可以使3d旋转效果更美观--达到电信电视首页的效果*/
    private void roateXAnima() {
        float w = ivb.getMeasuredWidth();
        float h = ivb.getMeasuredHeight();
        ObjectAnimator animator = ObjectAnimator.ofFloat(ivb , "rotationX" , 0f ,-360f);
        ivb.setPivotX(w * 2f);
        ivb.setPivotY(h/2);
        animator.setDuration(5000);
        animator.start();
    }

    private void transXYAnima2() {
        //动画效果，先从0.0移动到300.300--再变化透明度，再次点击动画一样
        ObjectAnimator movex = ObjectAnimator.ofFloat(iv, "translationX", 0f , 300f);
        ObjectAnimator movey = ObjectAnimator.ofFloat(iv, "translationY", 0f, 300f);
        ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(iv, "alpha", 1f, 0f, 1f);
        AnimatorSet animSet = new AnimatorSet();
//        animSet.play(movex).with(movey).before(fadeInOut);
//        animSet.playTogether(movex , movey , fadeInOut);
//        animSet.playSequentially(movey , movex , fadeInOut);
        animSet.setDuration(5000);
        animSet.start();
    }

    private void transYAnima() {
        //和transXAnima方法的注释一样
        //这个动画，一开始会迅速移动到300f位置，再开始动画
        //再次点击按钮之后，动画本身位置就在300f，所以会很流畅
//        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "translationY" , 300f  , -300f , 300f);
        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "translationY" , 0f  , 300f);
        animator.setDuration(2000);
        animator.start();
    }

    /**
     * 总的来说不论一个还是多个数字参数，都可以这么理解：
     * 1.第一个参数为初始状态，然后分别达到其他的状态
     * 2.第一个参数与界面最开始的状态不一样，就会迅速改变到初始状态，然后再开始动画
     * 3.所以一个参数时，重复点击按钮没有动画效果
     */
    private void transXAnima() {
        /** 有多个数字的参数--第一个数字表示动画初始状态--再次点击按钮后，会重复同样的动画--因为第一次动画结束坐标为300f*/
//        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "translationX" , 0f ,300f , 600f ,300f);
        /** 只有一个数字的参数--表示动画向X移动300f--再次点击按钮后，不会有任何动画效果*/
//        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "translationX" , 300f);

        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "translationX" , 0f ,300f);

//        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "translationX" , 300f  , 600f);
//        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "translationX" , 300f  , 600f , 900f);
        animator.setDuration(2000);
        animator.start();
    }

    private void alphaAnima2() {
        //属性动画结束之后，不会恢复到初始状态
        /** 从1f完全不透明 ---到0f 完全透明*/
//        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "alpha" , 1f , 0f );
        /** 从0f完全透明 ---到1f 完全不透明 --- 再到0f完全透明*/
        ObjectAnimator animator = ObjectAnimator.ofFloat(iv , "scaleX" , 0f , 1f , 0f );
        animator.setDuration(4000);
        animator.start();
    }

    private void shiTuAnima() {
        //动画结束之后，setFillAfter(true)保持动画最后的状态，默认setFillAfter(false)会恢复到初始状态
        //属性动画没有这个设置，属性动画是实实在在改变那个view的状态。视图动画只是显示效果。
//        alphaAnima();
//        roateAnima();
//        transAnima();
//        scaleAnima();
//        animaSet();
//        animaSet2();
//        animationListener();
    }

    private void animationListener() {
        TranslateAnimation ta = new TranslateAnimation(0 , 300 , 0 , 300);
        ta.setDuration(2000);
        final RotateAnimation ra = new RotateAnimation(0 , 360 , RotateAnimation.RELATIVE_TO_SELF , 0.5f , RotateAnimation.RELATIVE_TO_SELF , 0.5f);
        ra.setDuration(2000);
        ta.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                iv.startAnimation(ra);
                //这样做的效果是先移动动画、再回到原点、再旋转动画
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

        iv.startAnimation(ta);

    }

    private void animaSet2() {
        //用于测试AnimationSet的时间
        AnimationSet as = new AnimationSet(true);
        as.setDuration(2000);

        RotateAnimation ra = new RotateAnimation(0 , 360 , RotateAnimation.RELATIVE_TO_SELF , 0.5f , RotateAnimation.RELATIVE_TO_SELF , 0.5f);
        ra.setDuration(400);
        TranslateAnimation ta = new TranslateAnimation(0 , 300 , 0 , 300);
        ta.setDuration(100);


        as.addAnimation(ra);
        as.addAnimation(ta);

        iv2.startAnimation(as);
    }

    private void animaSet() {
        //设置了AnimationSet的时间之后，再对单独的动画设时间就没有意义了。1️以AnimationSet的时间为准
        AnimationSet as = new AnimationSet(true);
        as.setDuration(2000);

        RotateAnimation ra = new RotateAnimation(0 , 360 , RotateAnimation.RELATIVE_TO_SELF , 0.5f , RotateAnimation.RELATIVE_TO_SELF , 0.5f);
        ra.setDuration(40000);
        TranslateAnimation ta = new TranslateAnimation(0 , 300 , 0 , 300);
        ta.setDuration(10000);


        as.addAnimation(ra);
        as.addAnimation(ta);

        iv.startAnimation(as);

    }

    private void scaleAnima() {
        //参数一次为 开始x ，结束x ， 开始y ， 结束y 放大倍数
        ScaleAnimation sa = new ScaleAnimation(1 , 2 , 1 , 2);
        sa.setDuration(2000);
        iv.startAnimation(sa);
    }

    private void transAnima() {
        //参数一次为 开始x ，结束x ， 开始y ， 结束y 坐标
        TranslateAnimation ta = new TranslateAnimation(0 , 300 , 0 , 300);
        ta.setDuration(2000);
        iv.startAnimation(ta);
    }

    private void roateAnima() {
        int w = iv.getMeasuredWidth();
        int h = iv.getMeasuredHeight();
        //参数依次为  开始角度 ， 结束角度 ， 旋转中心点的x坐标，旋转的y坐标
        RotateAnimation ra = new RotateAnimation(0 , 180 , RotateAnimation.RELATIVE_TO_SELF , 0.5f , RotateAnimation.RELATIVE_TO_SELF , 0.5f);
//        RotateAnimation ra2 = new RotateAnimation(0 , 360 , w/2 , h/2); //这2中方法均为绕自身的中心点旋转
        ra.setFillAfter(true);
        ra.setDuration(2000);
        iv.startAnimation(ra);
    }

    private void alphaAnima() {
        //参数依次为  开始的透明度 ， 目标透明度  1为不透明，0为全透明
        AlphaAnimation aa = new AlphaAnimation(1 , 0);
        aa.setDuration(2000);
        iv.startAnimation(aa);
    }
}
